//
//  NSUserDefaults+QTAdd.m
//  QTCategory
//
//  Created by 张俊博 on 16/9/9.
//  Copyright © 2016年 CISDI. All rights reserved.
//

#import "NSUserDefaults+QTAdd.h"
#import "NSDate+QTAdd.h"
#import <QTConfig/QTConfig.h>
#import <UserNotifications/UserNotifications.h>
#import <PushKit/PushKit.h>
#import "UIDevice+QTAdd.h"
#import "QTCategoryMacro.h"
#import "NSObject+QTAdd.h"

#import <QTSvcShareExtension/QTSvcShareExtension.h>

static NSString * const kRefreshToken           = @"kRT";
static NSString * const kAccessToken            = @"kAT";
static NSString * const kTokenTime              = @"kTET";
static NSString * const kDomainID               = @"kDID";
static NSString * const kAccountID              = @"kAID";
static NSString * const kCurrentChat            = @"kCc";

static NSString * const kAccount                = @"kAct";
static NSString * const kDeviceID               = @"deviceId";
static NSString * const kDeviceToken            = @"deviceToken";
static NSString * const kDeviceVoipPushToken    = @"deviceVoipPushToken";
static NSString * const kCommonUseEmoji         = @"kCommonUseEmoji";
static NSString * const kBidaRead               = @"kBidaRead";

static NSString * const kEnterpriseName = @"kEName";

static NSString * const kAPPVersion             = @"appVersion";
static NSString * const kAPPLanguage            = @"appLanguage";

static NSString * const kShowVoiceChatAlertView = @"showVoiceChatAlertView";

static NSString * const kShowAuthAlertRedDot    = @"kShowAuthAlertRedDot";

static NSString * const kVoiceChatSessionStatus    = @"kVoiceChatSessionStatus";

@implementation NSUserDefaults (QTAdd)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        [QTExUserDefaults updateCurLanguage:[NSUserDefaults currentLanguage]];
    });
}

+ (void)clearUserDefaults {
    [NSUserDefaults clearRefreshToken];
    [NSUserDefaults clearAccessToken];
    [NSUserDefaults clearCurrentChat];
//    [NSUserDefaults clearDoaminID];
    [NSUserDefaults clearAccountID];
}

+ (void)resetDefaults {
    
    NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
    NSDictionary *dict = [defs dictionaryRepresentation];
    for(id key in dict) {
        [defs removeObjectForKey:key];
    }
    [defs synchronize];
}

+ (NSString *)refreshToken
{
    return [[NSUserDefaults standardUserDefaults] valueForKey:kRefreshToken];
}

+ (void)updateRefreshToken:(NSString *)refreshToken
{
    if (isNullStr(refreshToken)) {
        return;
    }
    
    [[NSUserDefaults standardUserDefaults] setValue:refreshToken
                                             forKey:kRefreshToken];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

+ (void)clearRefreshToken
{
    [[NSUserDefaults standardUserDefaults] removeObjectForKey:kRefreshToken];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

+ (NSString *)accessToken
{
    return [[NSUserDefaults standardUserDefaults] valueForKey:kAccessToken];
}

+ (void)updateAccessToken:(NSString *)accessToken
{
    if (isNullStr(accessToken)) {
        return;
    }
    [[NSUserDefaults standardUserDefaults] setValue:accessToken
                                             forKey:kAccessToken];
    [[NSUserDefaults standardUserDefaults] synchronize];
    
    //更新token刷新时间
    [NSUserDefaults updateAccessTokenRefreshTime:[NSDate date]];
}

+ (void)updateAccessTokenRefreshTime:(NSDate *)date
{
    [[NSUserDefaults standardUserDefaults] setValue:@([date timeIntervalSince1970])
                                             forKey:kTokenTime];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

+ (NSDate *)accessTokenRefreshTime
{
    NSString *interval = [[NSUserDefaults standardUserDefaults] valueForKey:kTokenTime];
    if (!interval) {
        return nil;
    }
    
    return [NSDate dateWithTimeIntervalSince1970:interval.doubleValue];
}

+ (BOOL)isTokenExpires
{
    NSDate *refreshDate = [NSUserDefaults accessTokenRefreshTime];
    if (!refreshDate) {
        return NO;
    }
    NSDate *now = [NSDate date];
    
    return [now timeIntervalSinceDate:refreshDate] > 9*60/*kTokenExpiresTime*/;
}

+ (void)clearAccessToken
{
    [[NSUserDefaults standardUserDefaults] removeObjectForKey:kAccessToken];
    [[NSUserDefaults standardUserDefaults] removeObjectForKey:kTokenTime];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

+ (NSString *)domainID
{
    return [[NSUserDefaults standardUserDefaults] valueForKey:kDomainID];
}

+ (void)updateDomainID:(NSString *)domainID
{
    [[NSUserDefaults standardUserDefaults] setValue:domainID
                                             forKey:kDomainID];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

+ (void)clearDoaminID
{
    [[NSUserDefaults standardUserDefaults] removeObjectForKey:kDomainID];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

+ (NSString *)accountID
{
    return [[NSUserDefaults standardUserDefaults] valueForKey:kAccountID];
}

+ (void)updateAccountID:(NSString *)accountID
{
    [[NSUserDefaults standardUserDefaults] setValue:accountID
                                             forKey:kAccountID];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

+ (void)clearAccountID
{
    [[NSUserDefaults standardUserDefaults] removeObjectForKey:kAccountID];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

+ (BOOL)hasLogin
{
    return !isNullStr([NSUserDefaults accountID]) && !isNullStr([NSUserDefaults domainID]);
}

+ (NSString *)loginAccount
{
    return [[NSUserDefaults standardUserDefaults] valueForKey:kAccount];
}

+ (void)updateLoginAccount:(NSString *)account
{
    [[NSUserDefaults standardUserDefaults] setValue:account
                                             forKey:kAccount];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

+ (NSString *)enterpriseName
{
    return [[NSUserDefaults standardUserDefaults] valueForKey:kEnterpriseName];
}

+ (void)updateEnterpriseName:(NSString *)enterpriseName
{
    [[NSUserDefaults standardUserDefaults] setValue:enterpriseName
                                             forKey:kEnterpriseName];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

+ (void)updateCurrentChat:(NSString *)chatId
{
    [[NSUserDefaults standardUserDefaults] setValue:chatId
                                             forKey:kCurrentChat];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

+ (void)clearCurrentChat
{
    [[NSUserDefaults standardUserDefaults] setValue:@""
                                             forKey:kCurrentChat];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

+ (NSString *)currentChat
{
    return [[NSUserDefaults standardUserDefaults] valueForKey:kCurrentChat];
}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
static NSString *deviceID = nil;
+ (NSString *)deviceID
{
    if (!isNullStr(deviceID)) {
        return deviceID;
    }
    
    //1、从文件读取
    NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"deviceId.txt"];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:filePath]) {
        deviceID = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
    }
    
    if (!isNullStr(deviceID)) {
        //写钥匙链
        [NSClassFromString(@"QTKeychain") performSelectorWithArgs:@selector(setPassword:forService:account:), deviceID, @"DeviceID", @"com.cisdi.qingtui"];
        //写NSUserDefaults
        [[NSUserDefaults standardUserDefaults] setValue:deviceID
                                                 forKey:kDeviceID];
        [[NSUserDefaults standardUserDefaults] synchronize];
        return deviceID;
    }
    
    //2、从钥匙链读取
    deviceID = [NSClassFromString(@"QTKeychain") performSelectorWithArgs:@selector(passwordForService:account:), @"DeviceID", @"com.cisdi.qingtui"];
    if (!isNullStr(deviceID)) {
        //写文件
        [deviceID writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
        //写NSUserDefaults
        [[NSUserDefaults standardUserDefaults] setValue:deviceID
                                                 forKey:kDeviceID];
        [[NSUserDefaults standardUserDefaults] synchronize];
        return deviceID;
    }
    
    //3、从NSUserDefaults读取
    deviceID = [[NSUserDefaults standardUserDefaults] valueForKey:kDeviceID];
    if (!isNullStr(deviceID)) {
        //写文件
        [deviceID writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
        //写钥匙链
        [NSClassFromString(@"QTKeychain") performSelectorWithArgs:@selector(setPassword:forService:account:), deviceID, @"DeviceID", @"com.cisdi.qingtui"];
        return deviceID;
    }
    
    //4、重新生成
    deviceID  = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
    //写文件
    [deviceID writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
    //写钥匙链
    [NSClassFromString(@"QTKeychain") performSelectorWithArgs:@selector(setPassword:forService:account:), deviceID, @"DeviceID", @"com.cisdi.qingtui"];
    //写NSUserDefaults
    [[NSUserDefaults standardUserDefaults] setValue:deviceID
                                             forKey:kDeviceID];
    [[NSUserDefaults standardUserDefaults] synchronize];
    return deviceID;
}
#pragma clang diagnostic pop

+ (NSString *)deviceToken
{
//    if (![UIApplication sharedApplication].isRegisteredForRemoteNotifications) {
//        return @"";
//    }
    
    if (kiOS10Later) {
        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
        center.delegate = (id)[UIApplication sharedApplication].delegate;
    }
    
    NSString *deviceToken = [[NSUserDefaults standardUserDefaults] valueForKey:kDeviceToken];
    
    NSString *cachesPath = [NSHomeDirectory() stringByAppendingPathComponent:@"/Library/Caches"];
    NSString *deviceTokenFile = [cachesPath stringByAppendingPathComponent:@"/deviceToken.txt"];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:deviceTokenFile]) {
        deviceToken = [NSString stringWithContentsOfFile:deviceTokenFile encoding:NSUTF8StringEncoding error:nil];
        [NSUserDefaults updateDeviceToken:deviceToken];
    }
    
    if (kiOS10Later) {
        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
        [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
            
        }];
    } else {
//        [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes: (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert) categories:nil]];
        [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes: (UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) categories:nil]];
    }
    
    [[UIApplication sharedApplication] registerForRemoteNotifications];
    
    if (deviceToken) {
        return deviceToken;
    } else {
        return @"";
    }
}

+ (void)updateDeviceToken:(NSString *)deviceToken
{
    NSString *tempToken = [NSString stringWithFormat:@"%@", deviceToken];
    
    tempToken = [tempToken stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    
    [tempToken stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    
    NSString *deviceTokenStr = [tempToken stringByReplacingOccurrencesOfString:@" " withString:@""];
    
    [[NSUserDefaults standardUserDefaults] setValue:deviceTokenStr
                                             forKey:kDeviceToken];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

+ (NSString *)deviceVoipPushToken {
    PKPushRegistry *voipRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
    voipRegistry.delegate = (id)[UIApplication sharedApplication].delegate;
    voipRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
    
    NSString *deviceVoipPushToken = [[self standardUserDefaults] valueForKey:kDeviceVoipPushToken];
    NSString *cachesPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Caches"];
    NSString *voipPushTokenFile = [cachesPath stringByAppendingPathComponent:@"/deviceVoipPushToken.txt"];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:voipPushTokenFile]) {
        deviceVoipPushToken = [NSString stringWithContentsOfFile:voipPushTokenFile encoding:NSUTF8StringEncoding error:nil];
        [self updateDeviceVoipPushToken:deviceVoipPushToken];
    }
    
    if (deviceVoipPushToken) {
        return deviceVoipPushToken;
    } else {
        return @"";
    }
}

+ (void)updateDeviceVoipPushToken:(NSString *)deviceVoipPushToken {
    if (isNullStr(deviceVoipPushToken)) {
        return;
    }
    NSString *tempToken = [NSString stringWithFormat:@"%@", deviceVoipPushToken];
    
    tempToken = [tempToken stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    
    [tempToken stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    
    NSString *deviceVoipPushTokenStr = [tempToken stringByReplacingOccurrencesOfString:@" " withString:@""];
    
    [[NSUserDefaults standardUserDefaults] setValue:deviceVoipPushTokenStr
                                             forKey:kDeviceVoipPushToken];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

+ (NSArray *)CommonUseEmojis {
    NSData *emojiUserData = [[NSUserDefaults standardUserDefaults] valueForKey:kCommonUseEmoji];
    if (!emojiUserData) return nil;
    NSDictionary *emojiUserDic = [[NSKeyedUnarchiver unarchiveObjectWithData:emojiUserData] mutableCopy];
    if (!emojiUserDic) return nil;
    
    NSDictionary *emojiDic = emojiUserDic[[NSUserDefaults domainID]];
    if (!emojiDic) return nil;
    
    NSArray *sortedKeys = [emojiDic keysSortedByValueUsingComparator:^NSComparisonResult(id obj1, id obj2) {
        return [obj2 compare:obj1];
    }];
    
    return [sortedKeys subarrayWithRange:NSMakeRange(0, MIN(20, sortedKeys.count))] ;
}

+ (void)UpdateEmoji:(NSString *)emoji {
    
    NSData *emojiUserData = [[NSUserDefaults standardUserDefaults] valueForKey:kCommonUseEmoji];
    NSMutableDictionary *emojiUserDic;
    if (emojiUserData) {
        emojiUserDic = [[NSKeyedUnarchiver unarchiveObjectWithData:emojiUserData] mutableCopy];
    }
    if (!emojiUserDic) {
        emojiUserDic = @{}.mutableCopy;
    };
    
    NSMutableDictionary *emojiDic = emojiUserDic[[NSUserDefaults domainID]];
    if (!emojiDic) {
        emojiDic = @{}.mutableCopy;
        emojiUserDic[[NSUserDefaults domainID]] = emojiDic;
    };
    
    emojiDic[emoji] =[NSDate date];
    
    
    [[NSUserDefaults standardUserDefaults] setValue:[NSKeyedArchiver archivedDataWithRootObject:emojiUserDic]
                                             forKey:kCommonUseEmoji];
    [[self standardUserDefaults] synchronize];
}

+ (void)DeleteEmojiWithUserId:(NSString *)userId {
    NSData *emojiUserData = [[NSUserDefaults standardUserDefaults] valueForKey:kCommonUseEmoji];
    if (!emojiUserData) return;
    NSMutableDictionary *emojiUserDic = [[NSKeyedUnarchiver unarchiveObjectWithData:emojiUserData] mutableCopy];
    if (!emojiUserDic) return;
    
    [emojiUserDic removeObjectForKey:[NSUserDefaults domainID]];
    
    [[NSUserDefaults standardUserDefaults] setValue:[NSKeyedArchiver archivedDataWithRootObject:emojiUserDic]
                                             forKey:kCommonUseEmoji];
    [[self standardUserDefaults] synchronize];
}

+ (void)updateAPPVersion {
    [[self standardUserDefaults] setValue:APPVersion forKey:kAPPVersion];
    [[self standardUserDefaults] synchronize];
}

+ (NSString *)appVersion {
    return [[self standardUserDefaults] objectForKey:kAPPVersion];
}

+ (BOOL)isCurLanguageZh_cn
{
    NSString *language = [[NSUserDefaults standardUserDefaults] valueForKey:kAPPLanguage];
    if (!language) {
        language = [UIDevice currentDevice].currentLanguageName;
        [self updateCurLanguage:language];
    }
    //简体中文 zh-Hans(iOS8) zh-Hans-CN(iOS9)
    //繁体中文 zh-Hant(iOS8) zh-Hant-CN(iOS9)
    //繁体中文(香港) zh-HK
    //繁体中文(台湾) zh-TW
    return [language hasPrefix:@"zh"];
}

+ (NSString *)currentLanguage {
    return [[NSUserDefaults standardUserDefaults] valueForKey:kAPPLanguage];
}

+ (void)updateCurLanguage:(NSString *)language
{
    [[self standardUserDefaults] setValue:language forKey:kAPPLanguage];
    [[self standardUserDefaults] synchronize];
    
    [QTExUserDefaults updateCurLanguage:language];
}

+ (BOOL)hasShowVoiceChatAlertView {
   return [[[self standardUserDefaults] objectForKey:kShowVoiceChatAlertView] boolValue];
}

+ (void)updateVoiceChatShowAlertView {
    [[self standardUserDefaults] setValue:@YES forKey:kShowVoiceChatAlertView];
    [[self standardUserDefaults] synchronize];

}

+ (BOOL)needShowLaunch {
    BOOL currentVersionDisplayLaunch = [QTConfig defaultConfig].currentVersionDisplayLaunch;
    if (![self appVersion]) {//没显示过launch
        //developer inhouse distribution版本才会有欢迎页面
        if ([QTConfig defaultConfig].appCode.integerValue == 0
            ||[QTConfig defaultConfig].appCode.integerValue == 2) {//需要显示launch
            [self updateAPPVersion];
            return YES;
        } else {//不需要显示
            [self updateAPPVersion];
            return NO;
        }
    } else {//显示过launch
        if ([[self appVersion] isEqualToString:APPVersion]) {//版本号一样，不需要显示
            return NO;
        } else {//版本号不一样
            if (currentVersionDisplayLaunch) {//需要显示launch
                [self updateAPPVersion];
                return YES;
            } else {//不需要显示launch
                [self updateAPPVersion];
                return NO;
            }
        }
    }
}



+ (BOOL)isBidaReadOpen
{
    return [[[NSUserDefaults standardUserDefaults] valueForKey:kBidaRead] boolValue];
}

+ (void)updateBidaRead:(BOOL)isOpen
{
    [[self standardUserDefaults] setValue:@(isOpen) forKey:kBidaRead];
    [[self standardUserDefaults] synchronize];
}

+ (BOOL)needShowAuthAlertRedDot:(NSString *)domain
{
    NSData *dicData = [[NSUserDefaults standardUserDefaults] valueForKey:kShowAuthAlertRedDot];
    NSMutableDictionary *dic = [[NSKeyedUnarchiver unarchiveObjectWithData:dicData] mutableCopy];
    if (!dicData) {
        dic = [NSMutableDictionary dictionary];
    }
    
    BOOL needShowRedDot = YES;
    if (dic[domain]) {
        needShowRedDot = [dic[domain] boolValue];
    } else {
        dic[domain] = @(needShowRedDot);
        [[NSUserDefaults standardUserDefaults] setValue:[NSKeyedArchiver archivedDataWithRootObject:dic]
                                                 forKey:kShowAuthAlertRedDot];
        [[self standardUserDefaults] synchronize];
    }
    
    return needShowRedDot;
}

+ (void)updateNeedShowAuthAlertRedDot:(NSString *)domain
{
    NSData *dicData = [[NSUserDefaults standardUserDefaults] valueForKey:kShowAuthAlertRedDot];
    NSMutableDictionary *dic = [[NSKeyedUnarchiver unarchiveObjectWithData:dicData] mutableCopy];
    if (!dicData) {
        dic = [NSMutableDictionary dictionary];
    }
    
    dic[domain] = @(NO);
    [[NSUserDefaults standardUserDefaults] setValue:[NSKeyedArchiver archivedDataWithRootObject:dic]
                                             forKey:kShowAuthAlertRedDot];
    [[self standardUserDefaults] synchronize];
}

+ (BOOL)voiceChatInSession {
    NSNumber *boolNumberValue = [[self standardUserDefaults] valueForKey:kVoiceChatSessionStatus];
    return boolNumberValue.boolValue;
}

+ (void)updateVoiceChatSessionStatus:(BOOL)sessionStatus {
    [[self standardUserDefaults] setValue:@(sessionStatus) forKey:kVoiceChatSessionStatus];
    [[self standardUserDefaults] synchronize];
}

@end


